package com.qualityevaluationclouduser.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.qualityevaluationclouduser.entity.*;
import com.qualityevaluationclouduser.repository.*;
import com.qualityevaluationclouduser.service.UserInfoService;
import com.qualityevaluationclouduser.untils.AuthMDA;
import com.qualityevaluationclouduser.untils.MD5Util;
import com.qualityevaluationclouduser.untils.MyPasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @program: qualityEvaluationCloudProject
 * @description: 用户信息业务实现
 * @author:
 * @create:
 **/
@Transactional
@Service
public class UserInfoServiceImpl implements UserInfoService {
    @Resource
    private UserInfoRepository userInfoRepository;
    @Resource
    EmaiAauthRepository emaiAauthRepository;
    @Autowired
    UserRoleReRepository userRoleReRepository;
    @Autowired
    MenuInfoRepository menuInfoRepository;
    @Autowired
    RoleFunctionRepository roleFunctionRepository;
    @Autowired
    RoleInfoRepository roleInfoRepository;
    @Value("${web.upload.path}")
    String basePath;

    @Transactional
    @Override
    public UserInfo findByName(String userName) {
        return userInfoRepository.findUserInfoByUsername(userName);
    }

    @Override
    public UserInfo addUserInfo(UserInfo userInfo, Long roleId) {
        if (userInfoRepository.existsUserInfoByUseraccount(userInfo.getUseraccount())) {
            throw new RuntimeException("登录账户已存在");
        }
        UserInfo save = new UserInfo();
        try {
            //用户密码加密
            userInfo.setPassword("" + (MD5Util.encode(userInfo.getPassword())).trim());
            userInfo.setCreationdate(new Date());
            save = userInfoRepository.save(userInfo);
            UserRoleRe userRoleRe = new UserRoleRe();
            userRoleRe.setUserid(save.getId());
            userRoleRe.setRoleid(roleId);
            userRoleRe.setCreationdate(new Date());
            userRoleRe.setRemark("默认角色");
            userRoleReRepository.save(userRoleRe);
        } catch (Exception e) {

            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
        return save;
    }

    @Override
    public void delUserInfo(String id) {
        try {
            UserInfo userInfo = userInfoRepository.findById(Long.parseLong(id)).get();
            if (null != userInfo) {
                userInfoRepository.delete(userInfo);
                userRoleReRepository.deleteUserRoleResByUserid(Long.parseLong(id));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public UserInfo modifyUserInfo(UserInfo userInfo) {
        UserInfo user1 = userInfoRepository.findById(userInfo.getId()).get();
        userInfo.setPassword(user1.getPassword());
        UserRoleRe userRoleRe = userRoleReRepository.findUserRoleReByUserid(userInfo.getId());
        userRoleRe.setRoleid(userInfo.getRoleId());
        userRoleReRepository.saveAndFlush(userRoleRe);
        return userInfoRepository.saveAndFlush(userInfo);
    }

    @Override
    public List<UserInfo> findAllUserInfos() {
        List<UserInfo> listAll = userInfoRepository.findAll();
//        List<User> resUsers=new ArrayList<>();
//        for (int i=0;i<listAll.size();i++){
//            User u=listAll.get(i);
//            u.setPassword("");
//            resUsers.add(u);
//        }
        return listAll;
    }

    @Override
    public void empower(String userId, String roleId) {
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(roleId))
            throw new RuntimeException("赋权失败，缺少参数");
        UserRoleRe userRoleRe = new UserRoleRe();
        userRoleRe.setUserid(Long.parseLong(userId));
        userRoleRe.setRoleid(Long.parseLong(roleId));
        userRoleRe.setCreationdate(new Date());
        userRoleReRepository.save(userRoleRe);
    }

    @Override
    public UserInfo register(MultipartFile file, UserInfo userInfo, Long roleId) throws IOException {
        String fileName = createFileName(userInfo);
        String filePath = basePath + fileName;
        boolean upload = upload(filePath, file);
        if (upload) {
            String avatar = AuthMDA.UPLOAD_PATH + fileName;
            userInfo.setAvatar(avatar);
        } else
            userInfo.setAvatar("");
        UserInfo result = addUserInfo(userInfo, roleId);
        return result;
    }

    @Override
    public void editPicture(MultipartFile file, UserInfo userInfo) throws IOException {
        UserInfo byId = userInfoRepository.findById(userInfo.getId()).get();
        if (null != byId) {
            String fileName = createFileName(userInfo);
            String filePath = basePath + fileName;
            boolean upload = upload(filePath, file);
            if (upload) {
                //写头像至磁盘后，应判断user信息中是否已有头像信息，将已有的删除
                String avatar1 = byId.getAvatar();
                if (null != avatar1 && !"".equals(avatar1)) {
                    String substring = avatar1.substring(8);
                    FileSystemUtils.deleteRecursively(new File(basePath + substring));
                }
                String avatar = AuthMDA.UPLOAD_PATH + fileName;
                byId.setAvatar(avatar);
            }
            userInfoRepository.saveAndFlush(byId);
        } else
            throw new RuntimeException("用户不存在");
    }

    @Override
    public Page<UserInfo> pageQueryUserInfoList(int page, int size) {
        return userInfoRepository.findAll(PageRequest.of(page - 1, size));
    }

    @Override
    public JSONObject editPicture(MultipartFile file, Long userId) throws IOException {
        UserInfo byId = userInfoRepository.findById(userId).get();
        JSONObject resPath = new JSONObject();
        if (null != byId) {
            String fileName = createFileName(byId);
            String filePath = basePath + fileName;
            boolean upload = upload(filePath, file);
            String avatar = "";
            if (upload) {
                //写头像至磁盘后，应判断user信息中是否已有头像信息，将已有的删除
//                String avatar1 = byId.getAvatar();
//                if (null != avatar1 && !"" .equals(avatar1) ) {
//                    String substring = avatar1.substring(8);
//                    FileSystemUtils.deleteRecursively(new File(basePath+substring));
//                }
                avatar = AuthMDA.UPLOAD_PATH + fileName;
                resPath.put("picPath", avatar);
                return resPath;
            }
            throw new IOException("头像编辑失败");
        } else
            throw new RuntimeException("用户不存在");

    }

    @Override
    public boolean resetPassword(String id, String password, String newPassword) {
        if (StringUtils.isEmpty(id))
            return false;
        UserInfo byAccount = userInfoRepository.findById(Long.parseLong(id)).get();
        MyPasswordEncoder myPasswordEncoder = new MyPasswordEncoder();
        boolean matches = myPasswordEncoder.matches(password, byAccount.getPassword());
        if (matches) {
            byAccount.setPassword(myPasswordEncoder.encode(newPassword.trim()));
            userInfoRepository.saveAndFlush(byAccount);
            return true;
        } else
            return false;
    }

    @Override
    public boolean changeState(Long userId) {
        UserInfo user = userInfoRepository.findById(userId).get();
        Integer usedstatus = user.getUsedstatus();
        if (AuthMDA.STATUS_ONE == usedstatus) {
            user.setUsedstatus(AuthMDA.STATUS_ZERO);
            userInfoRepository.saveAndFlush(user);
            return false;
        } else {
            user.setUsedstatus(AuthMDA.STATUS_ONE);
            userInfoRepository.saveAndFlush(user);
            return true;
        }
    }

    private boolean upload(String filePath, MultipartFile file) throws IOException {
        FileOutputStream fileOutputStream = null;
        if (file != null) {
            try {
                File file1 = new File(filePath);
                if (!file1.exists()) {
                    file1.createNewFile();
                }
                fileOutputStream = new FileOutputStream(file1);
                fileOutputStream.write(file.getBytes());
                fileOutputStream.flush();
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } finally {
                fileOutputStream.close();
            }
        } else {
            return false;
        }
    }

    @Override
    public void updatePassword(JSONObject jsonObject) {
        if (jsonObject == null)
            throw new RuntimeException("参数不能为空");
        String emailCode = jsonObject.getString("emailCode");
        EmaiAauth emaiAauth = emaiAauthRepository.findByEmailCode(emailCode);
        Date date = new Date();
        if ((date.getTime() - emaiAauth.getEmailCate().getTime()) / 1000 >= 60) {
            emaiAauthRepository.delete(emaiAauth);
            throw new RuntimeException("验证码已过期");
        }
        try {
            String newPassword = jsonObject.getString("newPassword");
            UserInfo user = userInfoRepository.findUserInfoByUsername(jsonObject.getString("username"));
            user.setPassword(newPassword);
            userInfoRepository.saveAndFlush(user);
            emaiAauthRepository.delete(emaiAauth);
        } catch (RuntimeException e) {
            emaiAauthRepository.delete(emaiAauth);
            throw new RuntimeException(e.getMessage());
        }

    }

    @Override
    public boolean findEmailCode(JSONObject jparms) {
        boolean res = false;
        try {//                       existsByEmailCodeAndEmailAddress
            res = emaiAauthRepository.existsByEmailCodeAndEmailAddress(jparms.getString("code"), jparms.getString("emailaddress"));
        } catch (RuntimeException e) {
            throw new RuntimeException(e.getMessage());
        }
        return res;
    }

    @Override
    public void deleteUserInfosByIdIn(List<Long> idList) {
        userInfoRepository.deleteUsersByIdIn(idList);
    }

    @Override
    public Page<UserInfo> pageQueryByAccountAndGenderAndStatus(String username, String gender, String mobile, String identifyCode, String version, String status, int page, int size) {

        Specification querySpecification = (Specification<UserInfo>) (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isEmpty(username)) {
                predicates.add(cb.like(root.get("username").as(String.class), "%" + username + "%"));
            }
            if (!StringUtils.isEmpty(gender)) {
                predicates.add(cb.equal(root.get("gender").as(Integer.class), Integer.valueOf(gender)));
            }
            if (!StringUtils.isEmpty(mobile)) {
                predicates.add(cb.like(root.get("mobile").as(String.class), "%" + mobile + "%"));
            }
            if (!StringUtils.isEmpty(identifyCode)) {
                predicates.add(cb.like(root.get("identifyCode").as(String.class), "%" + identifyCode + "%"));
            }
            if (!StringUtils.isEmpty(version)) {
                predicates.add(cb.equal(root.get("version").as(Integer.class), Integer.valueOf(version)));
            }
            if (!StringUtils.isEmpty(status)) {
                predicates.add(cb.equal(root.get("usedstatus").as(Integer.class), Integer.valueOf(status)));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        return userInfoRepository.findAll(querySpecification, PageRequest.of(page - 1, size));
    }

    @Override
    public List<MenuInfo> queryMenuInfoListByUser(Long userId) {
        List<MenuInfo> menuInfoList = new ArrayList<>();
        RoleInfo roleInfo = queryRoleInfoByUser(userId);
        if (null == roleInfo)
            return null;
        List<RoleFunction> roleFunctionList = roleFunctionRepository.findRoleFunctionsByRoleid(roleInfo.getId());
        for (RoleFunction roleFunction : roleFunctionList) {
            menuInfoList.add(menuInfoRepository.findById(roleFunction.getMenuid()).get());
        }
        return menuInfoList;
    }

    @Override
    public List<MenuInfo> queryMenuInfoListByRole(Long roleId) {
        List<MenuInfo> menuInfoList = new ArrayList<>();
        List<RoleFunction> roleFunctionList = roleFunctionRepository.findRoleFunctionsByRoleid(roleId);
        for (RoleFunction roleFunction : roleFunctionList) {
            menuInfoList.add(menuInfoRepository.findById(roleFunction.getMenuid()).get());
        }
        return menuInfoList;
    }

    @Override
    public RoleInfo queryRoleInfoByUser(Long userId) {
        UserRoleRe userRoleRe = userRoleReRepository.findUserRoleReByUserid(userId);
        if (null == userRoleRe)
            return null;
        RoleInfo roleInfo = roleInfoRepository.findById(userRoleRe.getRoleid()).get();
        return roleInfo;
    }

    @Override
    public Page<UserInfo> queryUserListByRole(Long userId, int page, int size) {
        RoleInfo roleInfo = queryRoleInfoByUser(userId);
        String rolename = roleInfo.getRolename();
        if (AuthMDA.SUPER_ADMIN.equals(rolename))
        {

        }
        return null;
    }


    private String createFileName(UserInfo user) {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = user.getUseraccount() + "-" + simpleDateFormat.format(date) + ".png";
        return fileName;
    }


}
